﻿using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ESRI.ArcGIS.Client.Tasks;

namespace ESRI.ArcGIS.Client.Async
{
    public static partial class GeometryServiceExtensions
    {
        /// <summary>
        /// Calculates the lengths of each specified polyline.
        /// </summary>
        /// <param name="task"></param>
        /// <param name="graphics">The graphics used to calculate lengths.</param>
        /// <param name="lengthUnit">The length unit in which perimeters of polygons will be calculated.
        /// If unit is not specified, the units are derived from the Spatial Reference of the geometry.</param>
        /// <param name="geodesic">If polylines are in geographic coordinate system, then geodesic needs to be set to true
        /// in order to calculate the ellipsoidal shortest path distance between each pair of the vertices in the polylines.
        /// The output if lengthUnit is not specified is returned in meters.</param>
        /// <returns></returns>
        public static Task<LengthsTaskResult> LengthsTaskAsync(this GeometryService task, IList<Graphic> graphics,
            LinearUnit? lengthUnit, bool geodesic)
        {
            return LengthsTaskAsync(task, graphics, lengthUnit, geodesic, CancellationToken.None);
        }

        /// <summary>
        /// Calculates the lengths of each specified polyline.
        /// </summary>
        /// <param name="task"></param>
        /// <param name="graphics"></param>
        /// <param name="lengthUnit">The length unit in which perimeters of polygons will be calculated.
        /// If unit is not specified, the units are derived from the Spatial Reference of the geometry.</param>
        /// <param name="geodesic">If polylines are in geographic coordinate system, then geodesic needs to be set to true
        /// in order to calculate the ellipsoidal shortest path distance between each pair of the vertices in the polylines.
        /// The output if lengthUnit is not specified is returned in meters.</param>
        /// <param name="cancellationToken">Cancellation token for cancelling task.</param>
        /// <returns></returns>
        public static Task<LengthsTaskResult> LengthsTaskAsync(this GeometryService task, IList<Graphic> graphics,
            LinearUnit? lengthUnit, bool geodesic, CancellationToken cancellationToken)
        {
            return task.HandleTask<GeometryService, LengthsEventArgs, LengthsTaskResult>(
                t => t.LengthsAsync(graphics, lengthUnit, geodesic, null),
                (t, e) => t.LengthsCompleted += e,
                (t, e) => t.LengthsCompleted -= e,
                e => new LengthsTaskResult(e),
                cancellationToken);
        }
    }
}